﻿using MoXAML.MVVM;
using MoXAML.MVVM.Common;
using MoXAML.Scrubber.Model;
using System.ComponentModel;

namespace MoXAML.Scrubber.ViewModel
{
    public class ScrubberOptionsViewModel : ValidationViewModelBase<ScrubberOptionsViewModel>, IDataErrorInfo
    {
        private ScrubberOptionsModel _model;
        private DelegateCommand<ScrubberOptionsViewModel> _saveCommand;
        private bool? _dialogResult;

        /// <summary>
        /// Instantiates a new instance of ScrubberOptionsViewModel.
        /// </summary>
        public ScrubberOptionsViewModel()
        {
            SetupValidation();
            _model = new ScrubberOptionsModel();
            _model.PropertyChanged += (s,e) =>
                {
                    OnChanged(e.PropertyName);
                };
        }

        /// <summary>
        /// Gets or sets the <see cref="DialogResult"/>.
        /// </summary>
        public bool? DialogResult
        {
            get { return _dialogResult; }
            set
            {
                if (_dialogResult == value) return;
                _dialogResult = value;
                OnChanged("DialogResult");
            }
        }

        public DelegateCommand<ScrubberOptionsViewModel> SaveCommand
        {
            get
            {
                if (_saveCommand == null)
                {
                    _saveCommand = new DelegateCommand<ScrubberOptionsViewModel>(SaveData, CanSaveData);
                }
                return _saveCommand;
            }
        }
        public bool ConvertTabsToSpaces
        {
            get
            {
                return _model.ConvertTabsToSpaces;
            }
            set
            {
                _model.ConvertTabsToSpaces = value;
            }
        }

        public int SpaceCount
        {
            get
            {
                return _model.SpaceCount;
            }
            set
            {
                // Validate and make sure the space count is greater than 1.
                _model.SpaceCount = value;
            }
        }

        public bool ForceLineMinimum
        {
            get
            {
                return _model.ForceLineMinimum;
            }
            set
            {
                _model.ForceLineMinimum = value;
            }
        }

        public bool RemoveCommonDefaults
        {
            get
            {
                return _model.RemoveCommonDefaults;
            }
            set
            {
                _model.RemoveCommonDefaults = value;
            }
        }

        public int Precision
        {
            get
            {
                return _model.Precision;
            }
            set
            {
                _model.Precision = value;
            }
        }

        public bool ReducePrecision
        {
            get
            {
                return _model.ReducePrecision;
            }
            set
            {
                _model.ReducePrecision = value;
            }
        }

        public bool ReorderAttributes
        {
            get
            {
                return _model.ReorderAttributes;
            }
            set
            {
                _model.ReorderAttributes = value;
            }
        }

        public int AttributeCountTolerance
        {
            get { return _model.AttributeCountTolerance; }
            set
            {
                _model.AttributeCountTolerance = value;
            }
        }

        #region IDataErrorInfo Members

        public string Error
        {
            get { return null; }
        }

        public string this[string columnName]
        {
            get 
            { 
                return PerformValidation(columnName, this); 
            }
        }

        #endregion

        /// <summary>
        /// Save the model data.
        /// </summary>
        private void SaveData(ScrubberOptionsViewModel vm)
        {
            _model.SaveModel();
            DialogResult = true;
        }

        private bool CanSaveData(ScrubberOptionsViewModel vm)
        {
            return (string.IsNullOrWhiteSpace(GetErrors(this))) ;
        }

        private void SetupValidation()
        {
            AddValidation("AttributeCountTolerance", s => ValidateAttributeCountTolerance(s));
            AddValidation("SpaceCount", s => ValidateSpaceCount(s));
            AddValidation("Precision", s => ValidatePrecision(s));
        }

        private static void ValidateSpaceCount(ScrubberOptionsViewModel vm)
        {
            if (vm.SpaceCount < 1)
                vm.AddFailure("Space count cannot be less than 1");
            if (vm.SpaceCount > 9)
                vm.AddFailure("SpaceCount cannot be greater than 9");
        }

        private static void ValidatePrecision(ScrubberOptionsViewModel vm)
        {
            if (vm.Precision < 1)
                vm.AddFailure("The precision cannot be less than 1");
            if (vm.Precision > 9)
                vm.AddFailure("Precision cannot be greater than 9");
        }

        private static void ValidateAttributeCountTolerance(ScrubberOptionsViewModel vm)
        {
            if (vm.AttributeCountTolerance < 1)
                vm.AddFailure("Tolerance cannot be less than 1");
            if (vm.AttributeCountTolerance > 9)
                vm.AddFailure("Tolerance cannot be greater than 9");
        }
    }
}